home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD Exchange
/
CD Exchange - Volume 1.iso
/
d.t.p
/
utils
/
others
/
pcal
/
writefil.c
< prev
Wrap
C/C++ Source or Header
|
1993-08-12
|
25KB
|
995 lines
/*
* writefil.c - Pcal routines concerned with writing the PostScript output
*
* Contents:
*
* def_footstring
* expand_fmt
* find_daytext
* find_holidays
* find_noteboxes
* print_db_word
* print_julian_info
* print_month
* print_moon_info
* print_dates
* print_pstext
* print_text
* print_word
* write_calfile
* write_psfile
*
* Revision history:
*
* 4.3 AWR 12/03/91 add support for -s flag (specify
* alternate date/fill box shading values)
*
* 4.2 AWR 10/08/91 add support for -[kK] flags (change
* position of small calendars)
*
* 10/03/91 add find_noteboxes(); revise to print
* text in multiple notes boxes
*
* add support for -S flag
*
* 10/02/91 modify def_footstring() to handle all
* types of strings; use it to print notes
* header (-N flag)
*
* 09/19/91 add write_calfile(), print_dates(),
* and new print_text() to generate
* input for Un*x "calendar" utility;
* renamed old print_text() as
* print_pstext() for clarity; revised
* to simplify setting working date
*
* 4.11 AWR 08/23/91 revise expand_fmt() to write results
* to string instead of stdout; revise
* print_word() to avoid writing null
* strings
*
* AWR 08/21/91 use ABBR_DAY_LEN and ABBR_MONTH_LEN
* (cf. pcallang.h) to print abbreviated
* day/month names
*
* AWR 08/21/91 add %u and %w (calculate week number
* so that 1/1 is always week 1); support
* %[+-]<n>[DWMY] to adjust working date
* by +|- <n> days/weeks/months/years
*
* 4.1 AWR 08/16/91 Support -G flag (outlined gray dates)
*
* 4.02 AWR 07/02/91 Added "%" expansions in text strings
* (cf. expand_fmt())
*
* 4.0 AWR 01/28/91 Support -B, -w flags and moon file
*
* 01/15/91 Extracted from pcal.c
*
*/
/*
* Standard headers:
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
/*
* Pcal-specific definitions:
*/
#include "pcaldefs.h"
#include "pcalglob.h"
#define WRITEFIL /* to get ordinal_suffix() from pcallang.h */
#include "pcallang.h"
#include "pcalinit.h" /* PostScript boilerplate */
/*
* Macros:
*/
/* make sure PRT() doesn't round "ph" up to 1.0 when printing it */
#define PRT_TWEAK(ph) ((ph) >= 0.9995 ? 0.0 : (ph))
/* advance working date by n days */
#define SET_DATE(n) do { \
MAKE_DATE(date, work_month, work_day + (n), work_year); \
normalize(&date); \
work_month = date.mm, work_day = date.dd, work_year = date.yy; \
} while (0)
/* reset working date to original date */
#define RESET_DATE \
work_month = this_month, work_day = this_day, work_year = this_year
/*
* Globals:
*/
/* order of following strings must conform to #define's in pcaldefs.h (q.v.) */
static char *cond[3] = {"false", "true", "(some)"};
static char *gray[3] = {"(gray)", "(outline)", "(outline_gray)"};
static int this_day, this_month, this_year; /* current day */
static int work_day, work_month, work_year; /* working day (cf. expand_fmt()) */
static char *kw_note, *kw_opt, *kw_year; /* keywords for -c output */
static int debug_text; /* generate debug output */
/*
* write_psfile - write PostScript code
*
* The actual output of the PostScript code is straightforward. This routine
* writes a PostScript header followed by declarations of all the PostScript
* variables affected by command-line flags and/or language dependencies. It
* the generates the PostScript boilerplate generated from pcalinit.ps, and
* finally calls print_month() to generate the PostScript code for each
* requested month.
*/
#ifdef PROTOS
void write_psfile(int month,
int year,
int nmonths)
#else
void write_psfile(month, year, nmonths)
int month; /* starting month */
int year; /* starting year */
int nmonths; /* number of months */
#endif
{
int i, ngray, nfsize;
char *p, **ap, tmp[STRSIZ];
debug_text = DEBUG(DEBUG_TEXT); /* debug text output? */
/*
* Write out PostScript prolog
*/
PRT("%%!PS-Adobe-1.0\n%%\t");
PRT(VERSION_MSG, progname, version);
if (*datefile)
PRT(DATEFILE_MSG, datefile);
PRT("\n%%\n");
/* font names and sizes (notes font only in 4.2) */
nfsize = (p = strrchr(notesfont, '/')) ? *p = '\0', atoi(p + 1) :
atoi(strrchr(NOTESFONT, '/') + 1);
PRT("/titlefont /%s def\n/dayfont /%s def\n/notesfont /%s def\n",
titlefont, dayfont, notesfont);
PRT("/notesfontsize %d def\n", nfsize);
/* month names */
PRT("/month_names [");
for (i = JAN; i <= DEC; i++) {
PRT(i % 6 == 1 ? "\n\t" : " ");
(void) print_word(months[i-1]);
}
PRT(" ] def\n");
/* day names - abbreviate if printing entire year on page */
PRT("/day_names [");
for (i = SUN; i <= SAT; i++) {
PRT(i % 6 == 0 && ! do_whole_year ? "\n\t" : " ");
strcpy(tmp, days[(i + first_day_of_week) % 7]);
if (do_whole_year)
tmp[ABBR_DAY_LEN] = '\0';
(void) print_word(tmp);
}
PRT(" ] def\n");
/* line separator */
PRT("/linesep ");
print_word(LINE_SEP);
PRT(" def\n");
/* colors (black/gray) to print weekdays and holidays */
PRT("/day_gray [");
for (ngray = 0, i = SUN; i <= SAT; ngray += day_color[i++] == GRAY)
PRT(" %s", cond[day_color[(i + first_day_of_week) % 7]]);
PRT(" ] def\n");
PRT("/holiday_gray %s def\n", cond[ngray <= 3]);
PRT("/logical_gray %s def\n", gray[num_style]);
/* rotation, scale, and translate values */
PRT("/rval %d def\n", rotate);
PRT("/xsval %s def\n/ysval %s def\n", xsval, ysval);
PRT("/xtval %s def\n/ytval %s def\n", xtval, ytval);
/* moon, Julian date, and box fill flags */
PRT("/draw-moons %s def\n", cond[draw_moons]);
PRT("/julian-dates %s def\n", cond[julian_dates]);
PRT("/fill-boxes %s def\n", cond[! blank_boxes]);
/* position of small calendars */
PRT("/prev_small_cal %d def\n", prev_cal_box[small_cal_pos]);
PRT("/next_small_cal %d def\n", next_cal_box[small_cal_pos]);
/* date and fill box shading values */
strcpy(tmp, shading);
*(p = strchr(tmp, '/')) = '\0';
PRT("/dategray %s def\n", tmp);
PRT("/fillgray %s def\n", p + 1);
/* PostScript boilerplate (part 1 of 1) */
for (ap = header; *ap; ap++)
PRT("%s\n", *ap);
PRT("\n");
/*
* Write out PostScript code to print calendars
*/
for (this_month = month, this_year = year; nmonths--; ) {
print_month(this_month, this_year);
this_year = NEXT_YEAR(this_month, this_year);
this_month = NEXT_MONTH(this_month, this_year);
}
}
/*
* write_calfile - write dates in format suitable for Un*x "calendar" utility
* (and subsequent use by Pcal)
*/
#ifdef PROTOS
void write_calfile(int month,
int year,
int nmonths)
#else
void write_calfile(month, year, nmonths)
int month; /* starting month */
int year; /* starting year */
int nmonths; /* number of months */
#endif
{
KWD *k;
/* look up the Pcal keywords (assumed present) for the -c output file */
for (k = keywds; k->name; k++) {
if (k->code == DT_NOTE) kw_note = k->name;
if (k->code == DT_OPT) kw_opt = k->name;
if (k->code == DT_YEAR) kw_year = k->name;
}
/* print the date style for subsequent use by Pcal */
PRT("%s -%c\n", kw_opt, date_style == USA_DATES ? F_USA_DATES :
F_EUR_DATES);
for (this_month = month, this_year = year; nmonths--; ) {
print_dates(this_month, this_year);
this_year = NEXT_YEAR(this_month, this_year);
this_month = NEXT_MONTH(this_month, this_year);
}
}
/*
* low-level utilities for PostScript generation
*/
/*
* expand_fmt - expand a strftime-like date format specifier; pcal supports
* %[aAbBdjmUWyY] from strftime() plus %[luwDM] and prefixes [0o+-] (see below);
* places expanded string in output buffer and returns pointer to character
* following end of format specifier. Assumes working date has been initialized
* (via RESET_DATE macro) prior to first call for a given text string
*/
#ifdef PROTOS
char *expand_fmt(char *buf,
char *p)
#else
char *expand_fmt(buf, p)
char *buf; /* output buffer (filled in) */
char *p; /* character following percent sign */
#endif
{
char c;
static char *prefixes = "0o+-";
int firstday, wkday;
int adjust = 0, print_lz = FALSE, ordinal = FALSE, prev_num = -1;
int num_present = FALSE, num_value = 0;
DATE date;
/* For